#include <stdio.h>



#include <ctype.h>





//E -> TE' 



//E' -> +TE' | e



//T -> FT'



//T' -> *FT' | e



//F -> NUM | (E)



//FIRST(E) = {NUM, LEFTB}



//FIRST(E') = {PLUS, e}



//FIRST(T) = {NUM, LEFTB}



//FIRST(T') = {MULT, e}



//FIRST(F) = {NUM, LEFTB}



//FOLLOW(E) = {$, RIGHTB}



//FOLLOW(E') = {$, RIGHTB}



//FOLLOW(T) = {PLUS, RIGHTB, $}



//FOLLOW(T') = {PLUS, RIGHTB, $}



//FOLLOW(F) = {MULT, PLUS, RIGHTB, $}





enum TOKEN {PLUS, MULT, NUM, END, ERR, LEFTB, RIGHTB};



char lookahead;



enum TOKEN token;



int num;



int error = 0;



FILE *fp;





void lexical(FILE *fp);



int match(enum TOKEN x);



int E();

int E_();



int T();



int T_();



int F();







//return 0 if success, return 1 otherwise



int match(enum TOKEN x) 

{

    if(token == x) 

        {

	

        	lexical(fp);



		return 0;



	}

        else

       {



		error = 1;



		return 1;



	}



}





//E -> TE'

 

int E()

 {



         switch(token)



	 {



	 case NUM:



	 case LEFTB:



	   return T()+E_();



	 default:



	   error=1;



	   return 1;

	  }



	 

}





//E_ -> +TE'|e

 

int E_()

 {



        switch(token)



	{



	 case PLUS:



	   match(token);



	   return T()+E_();



	 case RIGHTB:



	    return 0;



	 case END:



	  return 0;



	 default:



	  error=1;



	  return 1;



	}



           

}





//T -> FT'



int T()

{



        switch(token)



	{



	case NUM:



	case LEFTB:



	  return F()*T_();



        default:



	 error=1;



	 return 1;



	} 



	

}







//T' -> *FT' | e



int T_()

{ 

     switch(token)



	{



	 case MULT:



	  match(token);

	

          return F()*T_();



	 case PLUS:



         case RIGHTB:



	   return 1;



	 case END:



	  return 1;



	 default:



	  error=1;



	  return 1;



	}



      }



//F -> NUM | (E)



int F()

 {



        switch(token)



	{



	case NUM:



          if(!match(token))



	    {return num;}



	case LEFTB:



	  match(token);



	  int temp;



	  temp=E();



          match(token);



          return temp;



	case END:



	 return 1;



	default:



	 error=1;



	 return 1;



	}



       }



void lexical(FILE *fp)

 {





	lookahead = getc(fp);



	//num = 0;





	while(lookahead == ' ' || lookahead == '\t' || lookahead == '\n')

       {



		lookahead = getc(fp);



	}





	if(isdigit(lookahead))

        {



	        num=0;



		while(isdigit(lookahead))

                {



			token = NUM;



			num = num * 10 + lookahead - '0';



			lookahead = getc(fp);



		}



		ungetc(lookahead, fp);



		return;



	}

        else if(lookahead == '+')

       {



		token = PLUS;



		return;



	}

       else if (lookahead == '*')

       {



		token = MULT;



		return;



	}

        else if(lookahead == EOF)

       {



		token = END;



		return;



	}

        else if(lookahead == '(')

       {

		token = LEFTB;

		return;

	}

      else if(lookahead == ')') {

		token = RIGHTB;

		return;

	}

      else

     {



		error = 1;



		token = ERR;



		return;



	}



}





int main(int argc, char **argv)

 {



	int  res = 0;



	if(argc < 2)

        {



		printf("insufficient arguments");



		return 1;

   

	}



	fp = fopen(argv[1], "r");





	lexical(fp);



	res = E();



	if(!error)

        {

		printf("%d\n", res);

	}

       else {

		printf("There are errors\n");

	}



	

fclose(fp);



	return 0;





}

